Vaultで機密情報を管理する
Vaultとは
最近のアプリでは、データベースやAWS等、必ずといっていいほど外部システムとの連携があります。 その際に必要になるのが、パスワードやキー情報などの機密情報です。 そういった機密情報の管理は、特に注意しなければいけません。
例えば、大事なAWSキー情報やパスワードを、プログラム中やプロパティファイルに記述して、 それをGithubのようなリポジトリにpushしてしまったら、大変なことになってしまいます。
そういったミスをしないよう、安全に機密情報を管理するためのツールが、今回紹介するVaultです。
Vaultとは機密情報を管理するためのツールであり、クライアント/サーバ形式で動きます。 Vaultを使用するには、まずサーバを起動し、そこに対して機密情報を登録します。 その後、コマンドラインやHTTPでアクセスすることで、登録した情報を取得することができます。
Vaultの特徴は以下のとおりです。(Vault参考訳参照)
- 安全な機密情報ストレージ:任意のキー・バリュー情報を Vault に保管できます。これらの情報は一貫性のあるストレージに書き込まれる前に暗号化されるので、単なるストレージでは十分得られなかった機密情報に関するアクセスを提供します。Vaultはディスクだけでなく、Consul 等にも書き込めます。
-
動的な機密情報 :Vault は AWS や SQL データベースのように、複数のシステム向けにオンデマンドで機密情報を生成することができます。例えば、アプリケーションが S3 バケットにアクセスする必要があるとき、Vault に credential を訊ねると、Vault はオンデマンドで適切な権限を持つ AWS キーペアを生成します。動的に生成した後、使う必要がなくなれば Vault は自動的にそれらの情報を無効化します。
-
貸与と更新 :Vault における全ての機密情報は、それと結び付けられる貸与先の情報を持ちます。貸与が終わると、Vault は自動的に機密情報を無効化しします。クライアントは組み込み済み(ビルトイン)の API を使って、新しく情報を更新できます。
-
無効化:Vault は機密情報の無効化機能を内蔵しています。Vault が無効化できるのは単一の情報だけでなく、ツリー情報も扱えます。例えば、Vault は特定のユーザにおける読み込み全ての権限を無効化するか、特定のタイプに対する全ての権限を無効化できます。無効化機能は、不正侵入時におけるシステムの整理時、鍵のローリング(差し替え)を手助けします。これらはまた、組織において”brake glass”(ガラスを割る)ような手順の計画と訓練もできるようになります。
-
データ暗号化:Vault はデータの暗号化・複合化を保管せずに行えます。この機能によって、セキュリティ・チームによる暗号化パラメータの決定や、開発者は SQL データベースといった、各々の暗号方式で設計された場所上に、暗号化データをおく必要がなくなります。
-
Auditing:Vault の全てのアクセスは、複数の監査用バックエンドに送信できます。これにはVault のあらゆる種類のアクセス、例えば成功や失敗、設定、データへのアクセス等を含みます。監査ログは syslog やファイル等へ送信できます。複数の監査バックエンド機能により、監査ログの冗長化された複製を実現します。
-
複数の認証方式:Vault は認証に関する複数の方式(それぞれ独立しています)を取り込んでいますので、自分の組織にとって相応しいものを選ぶことができます。バージョン 0.1 でサポートしているのは、トークン、ユーザ名/パスワード、GitHub、certificates 等です。将来的には、更に多くものが追加されるでしょう。
VaultはKVSのように、キーバリュー情報を安全に保管でき、 AWS等いくつかのシステムに対しては動的にキー情報を生成することもできます。 また、機密情報には期限を設定したり、無効化することも可能です。 さらにVaultに対するすべてのアクセスは記録されており、確認することができます。
Vaultを使ってみる
動作環境
今回使用した動作環境は以下のとおりです。
- OS : MacOS X 10.9.4
Vaultのインストール
ではまず、Vaultのインストールからはじめましょう。 ここから自分のプラットフォームにあったファイルをダウンロードし、 解凍してパスを通すだけでOKです。
Vaultサーバ起動
インストールできたら、下記コマンドを実行します。
% vault server -dev ・ ・
このコマンドを実行すると、開発用のサーバとしてVaultサーバが起動します。 この状態でも暗号化はされますが、データはメモリ上に保存されますし、 再起動したらリセットされてしまうので注意してください。 とりあえず今回は確認用として使用します。
devサーバが起動したら、コンソールに次のような表示がされるはずです。
・ ・ The only step you need to take is to set the following environment variables: export VAULT_ADDR='http://127.0.0.1:8200' export VAULT_TOKEN='xxxxxxxxxxx' ・ ・
export部分をコンソールで実行し、環境変数を設定してください。あとで使用するvaultクライアントを動かすために必要です。 あとは「Unseal Key」と「Root Token」も覚えておいたほうがいいようです。(今回はとくに関係ありませんが)
次に、サーバがちゃんと起動しているか確認します。 次のように、vault statusコマンドで結果が返ってくればOKです。
% vault status Sealed: false Key Shares: 1 Key Threshold: 1 Unseal Progress: 0 High-Availability Enabled: false
Vaultクライアント操作
では、値を保存してみましょう。次のようにvault writeで値を保存します。
% vault write secret/foo value=bar Success! Data written to: secret/foo
上記コマンドは、「 value=bar 」を「 secret/foo 」のパスに保存します。パスは必ず「 secret/ 」から始まる必要があります。 なお、vault writeコマンドは値をファイルから読み込むこともできます。 コマンドラインを使用すると、その実行履歴が残るので、本番環境ではファイル読み込みが推奨されています。
保存した値を取得してみましょう。値の取得はvault readコマンドです。
% vault read secret/foo Key Value lease_id secret/hello/xxxxxxxxxxxxxxxxxxxx lease_duration 2592000 excited yes value bar
取得できました。また、json形式で結果を取得することもできます。
% vault read -format=json secret/foo { "lease_id": "secret/foo/xxxxxxxxxxxxxxxxxxxx", "lease_duration": 2592000, "renewable": false, "data": { "value": "bar" } }
このため、出力結果をパイプで繋いでjqとかで加工することも可能です。
値の削除はvault deleteです。
$ vault delete secret/foo Success! Deleted 'secret/foo'
なお、ここで説明した例も含め、Vaultが提供する全ての機能は、HTTP APIを使っても同じように行えるとのことです。 HTTP APIについては後日。
バックエンドについて
secretのバックエンド
先ほど値を保存したり読み出したりした場所は、「Secret Backend」と呼ばれる場所です。 上記例では「パスが secret/ からはじまらなければいけない」といっていました。 それは、genericと呼ばれるSecret Backendをマウントしたマウントポイントが「secret/」だからです。 Vaultでは、Secret Backendを任意のパスにマウントし、そのパスを使ってアクセスする必要があります。 ※ genericバックエンドは、バックエンド・ストレージに対してアクセスする
現在マウントされているバックエンドを確認するには、vault mountsを使用します。
% vault mounts Path Type Description secret/ generic generic secret storage sys/ system system endpoints used for control, policy and debugging
また、Vaultではいろいろなバックエンドをサポートしています。 ここに記述がありますが、AWSやMySQL等、いくつかのバックエンドがサポートされています。
バックエンドのマウント
では新しいバックエンドをマウントしてみます。バックエンドをマウントするにはmountで行います。
% vault mount generic Successfully mounted 'generic' at 'generic'!
標準では、マウントポイントはバックエンドと同じ名前になります。 ここでは、genericバックエンドを「generic/」にマウントしました。 vault mountsで確認してみましょう。
% vault mounts Path Type Description generic/ generic secret/ generic generic secret storage sys/ system system endpoints used for control, policy and debugging
これでgeneric/xxxとパスを指定すれば、値の保存や読み出しが可能になります。 ちなみに、gereric/とsecret/はデータの共有はしていないので注意してください。 バックエンドは他のバックエンドのデータにアクセスできません。
まとめ
今回は機密情報管理ツール「Vault」を少しだけ使ってみました。 まだまだたくさんの機能がありますが、これをちゃんと使うことで機密情報の管理が便利になりそうです。 次はVaultのHTTP APIについて確認する予定です。